package gazzera.node.core;

import gazzera.gui.*;
import gazzera.node.core.events.*;
import gazzera.node.core.messages.*;
import gazzera.node.core.peer.*;

import com.sleepycat.je.*;

public interface ICore
{

    /**
     * Broadcast a message to all connected nodes.
     * Note: the implementation may choose arbitrarily to exclude some
     * nodes, for example if there are too many connected or we are spamming
     * too much.
     * @param m the message to broadcast
     * @param excluded nodes to be excluded from broadcast
     */
    public void broadcast(Message m, Node... excluded);

    /**
     * Find the node corresponding to the given hash.
     * Note: nodes are only connected.
     * @param hash the hash to search
     * @return the corresponding node or null if not found or not currently connected.
     */
    public Node find(String hash);

    /**
     * Get our hash
     * @return
     */
    public String getHash();

    /**
     * Get the database with all our friends
     * @return
     */
    public Peoples getPeoples();

    /**
     * Enqueue an event to the Core main event queue.
     * @param event
     */
    public void enqueue(Event event);

    
    public void logErr(String s);

    public void logErr(String s, Throwable t);

    public void logErr(Throwable t);

    /**
     * Return the person representing our core
     * @return
     */
    public Person getOurPerson();

    /**
     * Get the gui to which this core is connected.
     * @return
     */
    public GuiInterface getGui();

    /**
     * Return true if the core is under heavy load (based on the length of the event queue).
     * @return
     */
    public boolean isBusy();

    /**
     * Connects somewhere. Node can be null if you just want to connect to a
     * location.
     * 
     * @param host
     * @param port
     * @param node
     */
    public void connect(String host, int port, Person person);

    /**
     * Start an asyncronous task
     * @param task
     */
    public void startTask(final Task task);

    /**
     * Get an instance of a plugin, if installed.
     * Useful for communication between plugins
     * @param <T>
     * @param cls
     * @return
     */
    public <T extends Plugin> T getPlugin(Class<T> cls);

    /**
     * Get the datastore environment, so that plugin can create their 
     * own datastores
     * @return
     */
    public Environment getEnvironment();

    /**
     * Return the configuration of the node.
     * @return
     */
    public Config getConfig();
}
